﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Helena.Models;
using Helena.Areas.Productos.Models;
using Helena.Areas.Ventas.Models;

namespace Helena.Areas.Reportes.Models
{
    public class LogicaKardex:InterfazLogicaKardex
    {
        DBContext Kardex_contexto = new DBContext();
        DBGenericQueriesUtil<Kardex> Tabla;
        LogicaProducto pro_db = new LogicaProducto(); 

        public DBContext context_publico { get { return Kardex_contexto; } }

        public LogicaKardex()
        {
            Tabla = new DBGenericQueriesUtil<Kardex>(Kardex_contexto,Kardex_contexto.t_Kardexs);
        }

        public void IngresarVenta(ProductoView producto, double cantidad, DateTime Fecha)
        {
            List<ProductoView> ProductoDetalle = Subproductos(producto.ID);
            if (ProductoDetalle.Count == 0)
            {
                // NO subproductos
                Kardex k = ExisteKardex(producto.ID, Fecha);
                if (k == null)
                {
                    k=CrearKardex(producto, Fecha);;
                }
                    k.Venta += cantidad;
                    k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                    ActualizarKardex(k.ID, k);
            }
            else
            {
                // es un producto compuesto
                foreach (ProductoView d in ProductoDetalle)
                {
                    ProductoView aux = pro_db.i_RetornarProductos().Where(p => p.Descripcion == d.Descripcion).FirstOrDefault() ;
                    // el aux es para agregarle el stock inicial
                    Kardex k = ExisteKardex(aux.ID, Fecha);
                    if (k == null)
                    {
                        k=CrearKardex(aux, Fecha);
                    }
                        k.Venta += cantidad * d.cantidad;
                        k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                        ActualizarKardex(k.ID, k);
                    
                }
            }
        }
        public void IngresarDegustacion(ProductoView producto, double cantidad, DateTime Fecha)
        {
            List<ProductoView> ProductoDetalle = Subproductos(producto.ID);
            if (ProductoDetalle.Count == 0)
            {
                // NO subproductos
                Kardex k = ExisteKardex(producto.ID, Fecha);
                if (k == null)
                {
                    k=CrearKardex(producto, Fecha);;
                }
                    k.Degustacion += cantidad;
                    k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                    ActualizarKardex(k.ID, k);
            }
            else
            {
                // es un producto compuesto
                foreach (ProductoView d in ProductoDetalle)
                {
                    Kardex k = ExisteKardex(d.ID, Fecha);
                    if (k == null)
                    {
                        k=CrearKardex(d, Fecha);
                    }
                        k.Degustacion += cantidad * d.cantidad;
                        k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                        ActualizarKardex(k.ID, k);
                }
            }
        }
        public void IngresarSalida(ProductoView producto, double cantidad, DateTime Fecha)
        {
            List<ProductoView> ProductoDetalle = Subproductos(producto.ID);
            if (ProductoDetalle.Count == 0)
            {
                // NO subproductos
                Kardex k = ExisteKardex(producto.ID, Fecha);
                if (k == null)
                {
                    k=CrearKardex(producto, Fecha);
                }
                    k.Salida += cantidad;
                    k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                    ActualizarKardex(k.ID, k);
            }
            else
            {
                // es un producto compuesto
                foreach (ProductoView d in ProductoDetalle)
                {
                    Kardex k = ExisteKardex(d.ID, Fecha);
                    if (k == null)
                    {
                        k = CrearKardex(d, Fecha);
                    }
                    k.Salida += cantidad * d.cantidad;
                    k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                    ActualizarKardex(k.ID, k);
                }
            }
        }
        public void IngresarEntrada(ProductoView producto, double cantidad, DateTime Fecha)
        {
            List<ProductoView> ProductoDetalle = Subproductos(producto.ID);
            if (ProductoDetalle.Count == 0)
            {
                // NO subproductos
                Kardex k = ExisteKardex(producto.ID, Fecha);
                if (k == null)
                {
                    k=CrearKardex(producto, Fecha);
                }
                    k.Entrada += cantidad;
                    k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                    ActualizarKardex(k.ID, k);
            }
            else
            {
                // es un producto compuesto
                foreach (ProductoView d in ProductoDetalle)
                {
                    Kardex k = ExisteKardex(d.ID, Fecha);
                    if (k == null)
                    {
                        k = CrearKardex(d, Fecha);
                    }
                    k.Entrada += cantidad * d.cantidad;
                    k.CantidadFinal = k.CantidadInicial + k.Entrada - k.Salida - k.Degustacion - k.Venta;
                    ActualizarKardex(k.ID, k);
                }
            }   
        }

        private List<ProductoView> Subproductos(int ProductoID)
        {
            List<DetalleProductoView> detalles = pro_db.DetallesDeUnProducto(ProductoID);
            List<ProductoView> salida = new List<ProductoView>();

            foreach (DetalleProductoView d in detalles)
            {
                ProductoView p = pro_db.i_RetornarProducto(d.ProductoSID);
                p.cantidad = d.Cantidad;
                p.Estado = d.Estado;
                p.precioventa = d.PrecioVenta;
                salida.Add(p);
            }
            return salida;
        }
        private Kardex ExisteKardex(int ProductoID, DateTime Fecha)
        {
            IEnumerable<Kardex> kardex = from u in Tabla.retornarTodos()
                                         where u.Fecha.DayOfYear == Fecha.DayOfYear && u.ProductoID == ProductoID
                                         select u;
            
            if (kardex == null)
            {
                return null;
            }
            else
            {
                return kardex.SingleOrDefault();
            }
        }
        private Kardex CrearKardex(ProductoView producto, DateTime Fecha)
        {
            Kardex kardex = new Kardex(Fecha, producto);
            kardex.CantidadInicial=pro_db.i_RetornarProducto(producto.ID).cantidad;
            Tabla.agregarElemento(kardex);
            return kardex;
        }
        private void ActualizarKardex(int ID, Kardex k)
        {
            Tabla.modificarElemento(k, ID);
        }

        public List<Kardex> MostrarKardexMensual(DateTime Fecha)
        {
            return Tabla.retornarTodos().Where(k=>k.Fecha.Month==Fecha.Month).ToList();
        }
        public List<Kardex> MostrarKardexDiario(DateTime Fecha)
        {
            return Tabla.retornarTodos().Where(k=>k.Fecha.DayOfYear==Fecha.DayOfYear).ToList();
        }


    }
}